package com.eian.boot.module.system.associations.user.dept.service;

import com.eian.boot.common.core.enums.CommonEnum;
import com.eian.boot.module.system.associations.user.dept.event.UserDeptAssignedEvent;
import com.eian.boot.module.system.associations.user.dept.mapper.UserDeptMapper;
import com.eian.boot.module.system.associations.user.dept.model.entity.SysUserDeptEntity;
import com.eian.boot.mybatis.core.service.BaseService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static com.eian.boot.table.Tables.sys_user_dept;

/**
 * 用户部门关系管理服务
 * 职责：纯粹的关系数据管理，不包含业务逻辑验证
 *
 * @author alex.meng
 * @since 1.0.0
 */
@Slf4j
@Service
public class UserDeptRelationService extends BaseService<UserDeptMapper, SysUserDeptEntity> {

    private final ApplicationEventPublisher eventPublisher;

    public UserDeptRelationService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    /**
     * 分配用户部门
     * 先清除旧关系，再建立新关系（包含主部门和兼职部门）
     *
     * @param userId      用户ID
     * @param mainDeptId  主部门ID
     * @param partDeptIds 兼职部门ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void assignUserDept(Long userId, Long mainDeptId, List<Long> partDeptIds) {
        log.debug("分配用户部门: userId={}, mainDeptId={}, partDeptIds={}",
                userId, mainDeptId, partDeptIds);

        // 删除用户现有部门关联
        this.remove(QueryWrapper.create()
                .from(sys_user_dept)
                .where(sys_user_dept.user_id.eq(userId)));

        // 添加主部门
        SysUserDeptEntity mainDept = SysUserDeptEntity.builder()
                .userId(userId)
                .deptId(mainDeptId)
                .isMain(CommonEnum.YES.getValue())
                .build();
        this.save(mainDept);

        // 添加兼职部门
        if (partDeptIds != null && !partDeptIds.isEmpty()) {
            List<SysUserDeptEntity> partDepts = new ArrayList<>();
            for (Long deptId : partDeptIds) {
                SysUserDeptEntity partDept = SysUserDeptEntity.builder()
                        .userId(userId)
                        .deptId(deptId)
                        .isMain(CommonEnum.NO.getValue())
                        .build();
                partDepts.add(partDept);
            }
            this.saveBatch(partDepts);
        }

        // 发布领域事件
        eventPublisher.publishEvent(new UserDeptAssignedEvent(this, userId, mainDeptId, partDeptIds));
    }

    /**
     * 获取用户主部门ID
     *
     * @param userId 用户ID
     * @return 主部门ID
     */
    public Long getMainDeptIdByUserId(Long userId) {
        SysUserDeptEntity userDept = this.queryChain()
                .from(sys_user_dept)
                .where(sys_user_dept.user_id.eq(userId))
                .and(sys_user_dept.is_main.eq(CommonEnum.YES.getValue()))
                .one();

        return userDept != null ? userDept.getDeptId() : null;
    }

    /**
     * 获取用户所有部门ID
     *
     * @param userId 用户ID
     * @return 部门ID列表
     */
    public List<Long> getAllDeptIdsByUserId(Long userId) {
        return this.queryChain()
                .select(sys_user_dept.dept_id)
                .from(sys_user_dept)
                .where(sys_user_dept.user_id.eq(userId))
                .listAs(Long.class);
    }

    /**
     * 级联删除：当用户被删除时调用
     * 清理用户的所有部门关系
     *
     * @param userId 用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cascadeDeleteByUserId(Long userId) {
        log.debug("级联删除用户部门关系: userId={}", userId);

        this.remove(QueryWrapper.create()
                .from(sys_user_dept)
                .where(sys_user_dept.user_id.eq(userId)));
    }
}

